package wx_article_catcher

import (
	"flag"
	"fmt"
	"github.com/bitly/go-simplejson"
	"os"
	"strings"
	"time"
	"webDownloader/engine/base"
	"webDownloader/engine/generic"
	"webDownloader/engine/wx_article_catcher/utils"
)

func init() {
	generic.RegisterEngine(&EngineWxAlbum{})
}

type EngineWxAlbum struct {
	generic.EngineGeneric
}

func (e *EngineWxAlbum) Accept(url string) bool {
	//fmt.Println("免费功能，权限校验无条件通过")
	return strings.Contains(url, "://mp.weixin.qq.com") && strings.Contains(url, "mp/appmsgalbum?")
}

func (e *EngineWxAlbum) ParseConfig() *map[string]interface{} {
	fmt.Println("正在解析命令行配置...")
	// 声明配置
	numArticle := flag.Int("n", -1, "指定下载文章的数量，为整数，0表示不下载（无意义），负值表示全部下载，默认值-1")
	savePath := flag.String("p", "./", "用于指定下载路径，默认为下载到当前工作目录，带空格的路径需要用引号包裹")
	book := flag.Bool("b", false, "用于指定处理成对pandoc友好的格式，方便制作电子书")
	offset := flag.Int("off", 0, "偏移量，指定偏移量后程序会跳过一定数量的文章，直接从后面开始下载，默认值0")
	numThreads := flag.Int("t", 10, "协程数，在一般情况下等价于允许同时下载的文章数，默认值10")
	printCss := flag.Bool("css", false, "输出评论区的css样式文件，用于部署静态页面，若没有此文件评论区格式会出错")
	keepPaidArticle := flag.Bool("keep", false, "保留未购买的付费文章，不加此参数未购买的付费文章不会被保存到本地，防止覆盖从他人处获取的已购文章")
	hideDonate := flag.Bool("d", false, "在下载完成后不显示捐助信息，直接退出")
	flag.Parse()

	// 填充至配置对象
	e.Conf["numArticle"] = *numArticle

	// 存储路径必须以 "/" 结尾，简化后续处理步骤
	path := *savePath
	if !strings.HasSuffix(path, "/") {
		path += "/"
	}

	e.Conf["savePath"] = path
	e.Conf["book"] = *book
	e.Conf["offset"] = *offset
	e.Conf["numThreads"] = *numThreads
	e.Conf["printCss"] = *printCss
	e.Conf["keep"] = *keepPaidArticle
	e.Conf["hideDonate"] = *hideDonate

	SetThreads(*numThreads)

	return &e.Conf
}

func albumEnvInit(e *EngineWxAlbum) error {
	path := e.Conf["savePath"].(string)
	err := os.MkdirAll(path, 0755)
	if err != nil {
		return err
	}
	css := e.Conf["printCss"].(bool)
	if !css {
		return nil
	}
	file, _ := os.OpenFile(path+"wxMessage.css", os.O_RDWR|os.O_CREATE, 0666)
	_, _ = file.WriteString(utils.CSS)
	_ = file.Close()
	return fmt.Errorf("优先打印css，不再执行下载流程")
}

func parseAlbum(baseUrl string, e *EngineWxAlbum) {
	relativeTime := time.Now().Unix()
	articleList := &e.Tasks
	num := e.Conf["numArticle"].(int)

	for true {
		url := baseUrl + e.Conf["beginMsgId"].(string)
		//fmt.Println(url)
		resp := utils.WxRequest(url, &e.Conf, false)
		newJson, _ := simplejson.NewJson(resp)
		albumResp := newJson.Get("getalbum_resp")
		// 判断是否要继续
		continueFlag := albumResp.Get("continue_flag").MustString()
		if continueFlag != "1" {
			break
		}
		array := albumResp.Get("article_list").MustArray()
		//fmt.Println(string(resp))
		for _, articleObj := range array {
			obj := articleObj.(map[string]interface{})
			e.Conf["beginMsgId"] = obj["msgid"].(string)
			//fmt.Println(index, article_obj)
			article := DownloadTaskWxArticle{Context: e}
			article.Url = obj["url"].(string)
			article.FileName = obj["title"].(string)
			article.Date = relativeTime
			*articleList = append(*articleList, &article)
			relativeTime -= 86400
			// 达到了指定的数量
			if len(*articleList) >= num && num >= 0 {
				return
			}
		}
		if len(*articleList) >= num && num >= 0 {
			return
		}
	}
}

func (e *EngineWxAlbum) ParseDownloadTask() []base.IDownload {
	e.Tasks = make([]base.IDownload, 0)

	cookies := map[string]string{}
	e.Conf["cookies"] = cookies

	err := albumEnvInit(e)
	if err != nil {
		fmt.Println("程序中止，原因: ", err)
		os.Exit(-1)
	}

	baseUrl := e.Conf["refUrl"].(string)
	data := utils.WxRequest(baseUrl, &e.Conf, false)
	response_data := string(data)
	app_msg_tokens := utils.TokenReg.FindAllStringSubmatch(response_data, 1)
	if len(app_msg_tokens) > 0 {
		//获取到了密钥就填入配置中
		e.Conf["appMsgToken"] = app_msg_tokens[0][1]
	}
	datamsgids := utils.DataMsgIdReg.FindAllStringSubmatch(response_data, 1)
	if len(datamsgids) > 0 {
		// 从这个文件开始下载
		e.Conf["beginMsgId"] = datamsgids[0][1]
	}
	// https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzU5ODM3OTI0Mg==&scene=1&album_id=1383164489876766722&count=3#wechat_redirect
	// https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzU5ODM3OTI0Mg==&scene=1&album_id=1383164489876766722&count=10&begin_msgid=2247487471
	if strings.Contains(baseUrl, "#") {
		baseUrl = baseUrl[0 : strings.Index(baseUrl, "#")-1]
	}
	baseUrl = strings.Replace(baseUrl, "&scene=", "&count=10&begin_itemidx=1&f=json&scene=", 1)
	// 只要得到begin_msgid 就可以一路往下查询了
	baseUrl += "&begin_msgid="

	parseAlbum(baseUrl, e)
	return e.Tasks
}

func (e *EngineWxAlbum) SyncDownloadTask() []base.IDownload {
	// 对下载任务进行同步（去掉已完成的任务），在单篇下载器中不做处理
	tasks := make([]base.IDownload, 0)
	for _, task := range e.Tasks {
		article := task.(interface{}).(*DownloadTaskWxArticle)
		// 对文件名进行规范化
		article.FileName = utils.IllegalChar1.ReplaceAllString(article.FileName, "_")
		article.FileName = utils.IllegalChar2.ReplaceAllString(article.FileName, "")
		filePath := e.Conf["savePath"].(string) + article.FileName + ".html"
		fileDesc, _ := os.Stat(filePath)
		if fileDesc != nil {
			fmt.Printf("文章【%s】已存在，判定为已下载，跳过\n", article.FileName)
		}
		tasks = append(tasks, article)
	}
	return tasks
}
